/*
 * Copyright (C) 2011 Michael Widmer <widmm8@bfh.ch>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ch.bfh.aeneas.navigation.track;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import ch.bfh.aeneas.R;
import ch.bfh.aeneas.exchange.intent.AeneasIntent;
import ch.bfh.aeneas.exchange.data.Node;
import ch.bfh.aeneas.navigation.app.NavigationActivity;
import ch.bfh.aeneas.navigation.app.NavigationService.NavigationServiceBinder;


/**
 * TrackMe records a route, the user is currently walking on. The recording 
 * starts right after the user has entered a name for the route.
 * @author Michael Widmer <widmm8@bfh.ch>
 */
public class TrackMe extends NavigationActivity implements View.OnClickListener {
    private ServiceConnection mTrackConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName arg0, IBinder arg1) {
            mTrackService = (TrackService)((NavigationServiceBinder) arg1).getService();
            mTrackService.addOnStateListener(mStateListener);
            mServiceReady = true;
            checkRequirements();
        }

        public void onServiceDisconnected(ComponentName arg0) {
            Log.i(LOG_TAG, "Service disconnected!");
            mServiceReady = false;
        }        
    };
    
    private Runnable mUpdater = new Runnable() {
        public void run() {
            checkForUpdate();
            mTimer.postDelayed(this, mFrequency);
        }
    };
    
    private String LOG_TAG = "TrackMe";
    protected TrackService mTrackService;
    private String mRouteName;
    private boolean mServiceReady;
    private boolean mTracking;
    private boolean mReadyForTracking;
    private Handler mTimer;
    private long mFrequency;
    private Node mLastAddedNode;
    private Node mCurrentNode;
    private Button mStartButton;
    private Button mStopButton;
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle, R.layout.trackme);
        
        //Log.i(LOG_TAG, "onCreate in TrackMe!");
        
        //setContentView(R.layout.trackme);
        
        mStartButton = (Button) findViewById(R.id.send_track_request);
        mStartButton.setEnabled(false);
        mStartButton.setOnClickListener(this);
        
        mStopButton = (Button) findViewById(R.id.send_track_stop);
        mStopButton.setEnabled(false);
        mStopButton.setOnClickListener(this);
        
        mServiceReady = false;
        mTracking = false;
        
        mTimer = new Handler();
        
        mFrequency = 10000L;
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onResume() {
        super.onResume();
        //Log.i(LOG_TAG, "onResume in TrackMe!");
        bindService(new Intent(this, TrackService.class), mTrackConnection, BIND_AUTO_CREATE);
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onPause() {
        //Log.i(LOG_TAG, "onPause in TrackMe!");
        unbindService(mTrackConnection);
        mTimer.removeCallbacks(mUpdater);
        mTrackService = null;
        mServiceReady = false;
        super.onPause();
    }

    @Override
    /**
     * {@inheritDoc}
     */
    public void onStop() {
        //Log.i(LOG_TAG, "onStop in TrackMe!");
        super.onStop();
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onDestroy() {        
        //Log.i(LOG_TAG, "onDestroy in TrackMe!");
        super.onDestroy();
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //Log.i(LOG_TAG, "onActivityResult in TrackMe!");
        if(requestCode == 1) {
            if(resultCode == Activity.RESULT_OK) {
                if(data.hasExtra("input")) {
                    mRouteName = data.getStringExtra("input");
                    mReadyForTracking = true;
                    return;
                }
            }
            askForRouteName();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void onClick(View arg0) {
        if(arg0 == mStartButton) {
            acquireWakeLock();

            mStartButton.setEnabled(false);
            mStopButton.setEnabled(true);
            if(!mTracking) {
                askForRouteName();
            }
        } else if(arg0 == mStopButton) {
            mTimer.removeCallbacks(mUpdater);
            releaseWakeLock();

            mStopButton.setEnabled(false);
            mStartButton.setEnabled(true);
            mTrackService.stopTracking();
            mTracking = false;
        }
    }

    @Override
    /**
     * {@inheritDoc}
     */
    protected void onPositionConnected() {
        checkRequirements();
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onPositionReceivedFirst(Location l) {
       Log.i(LOG_TAG, "position received!");
        mStartButton.setEnabled(true&&!mTracking);
        speech(getString(R.string.track_start_available));
    }

    private void checkRequirements() {
        //Log.i(LOG_TAG, "checking requirements");
        if(mServiceReady && super.isPositionManagerReady()) {
            //Log.i(LOG_TAG, "Start listening");
            super.startListening();
            
            if(mReadyForTracking) {
                Log.i(LOG_TAG, "Actually i was ready for tracking...");
                startTracking();
            } else if(mTracking) {
                Log.i(LOG_TAG, "Restart tracking...");
                track();
            } else {
                Log.i(LOG_TAG, "Wether tracking nor ready for it...");
            }
        }
    }

    private void askForRouteName() {
        Log.i(LOG_TAG, "asked for route name!");
        
        Intent i = new Intent(AeneasIntent.ACTION_INPUT);
        i.addCategory(AeneasIntent.CATEGORY_DATA);
        i.putExtra("title", getString(R.string.track_title_string_input));
        
        startActivityForResult(i, 1);
    }
    
    private void startTracking() {
        mReadyForTracking = false;
        mTracking = true;        
        mTrackService.startTracking(mRouteName);
    }
    
    /**
     * Start new timeout.
     */
    private void track() {
        mTimer.postDelayed(mUpdater, mFrequency);
    }

    /**
     * Gets called after timeout for new position has ended.
     */
    private void checkForUpdate() {
        Log.v(LOG_TAG, "Checking for update!");
        
        mTrackService.addWayPoint(mLastLocation);
    }

    @Override
    /**
     * {@inheritDoc}
     */
    protected void onStateReady() {
        Log.i(LOG_TAG, "Service ready! So starting to check for loc-updates!");        
        track();
    }
}